#include "mapedit.h"
#include <QDebug>
#include "opencv2/core/core.hpp"
#include "opencv2/opencv.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgcodecs/imgcodecs.hpp"

QPixmap cvMatToQPixmap(const cv::Mat &inMat)
{

    // QString qFilename = QFileDialog::getOpenFileName();
    // cv::Mat image = cv::imread(qFilename.toLocal8Bit().data());

    switch (inMat.type())
    {
    // 8-bit, 4 channel
    case CV_8UC4:
    {
        QImage image(inMat.data, inMat.cols, inMat.rows, static_cast<int>(inMat.step), QImage::Format_ARGB32);
        return QPixmap::fromImage(image);
    }
    // 8-bit, 3 channel
    case CV_8UC3:
    {
        QImage image(inMat.data, inMat.cols, inMat.rows, static_cast<int>(inMat.step), QImage::Format_RGB888);
        return QPixmap::fromImage(image.rgbSwapped());
    }
    // 8-bit, 1 channel
    case CV_8UC1:
    {
        static QVector<QRgb> sColorTable;
        // only create our color table once
        if (sColorTable.isEmpty())
        {
            for (int i = 0; i < 256; ++i)
                sColorTable.push_back(qRgb(i, i, i));
        }
        QImage image(inMat.data, inMat.cols, inMat.rows, static_cast<int>(inMat.step), QImage::Format_Indexed8);
        image.setColorTable(sColorTable);
        return QPixmap::fromImage(image);
    }
    default:
        break;
    }

    return QPixmap();
}

//将QImage转化为Mat
cv::Mat QImageToCvMat( const QImage &inImage, bool inCloneImageData = true )
{
    switch ( inImage.format() )
    {
    // 8-bit, 4 channel
    case QImage::Format_ARGB32:
    case QImage::Format_ARGB32_Premultiplied:
    {
        cv::Mat  mat( inImage.height(), inImage.width(),
                    CV_8UC4,
                    const_cast<uchar*>(inImage.bits()),
                    static_cast<size_t>(inImage.bytesPerLine())
                    );

        return (inCloneImageData ? mat.clone() : mat);
    }

        // 8-bit, 3 channel
    case QImage::Format_RGB32:
    case QImage::Format_RGB888:
    {
        if ( !inCloneImageData )
        {
            qWarning() << "CVS::QImageToCvMat() - Conversion requires cloning because we use a temporary QImage";
        }

        QImage   swapped = inImage;

        if ( inImage.format() == QImage::Format_RGB32 )
        {
            swapped = swapped.convertToFormat( QImage::Format_RGB888 );
        }

        swapped = swapped.rgbSwapped();

        return cv::Mat( swapped.height(), swapped.width(),
                       CV_8UC3,
                       const_cast<uchar*>(swapped.bits()),
                       static_cast<size_t>(swapped.bytesPerLine())
                       ).clone();
    }

        // 8-bit, 1 channel
    case QImage::Format_Indexed8:
    {
        cv::Mat  mat( inImage.height(), inImage.width(),
                    CV_8UC1,
                    const_cast<uchar*>(inImage.bits()),
                    static_cast<size_t>(inImage.bytesPerLine())
                    );

        return (inCloneImageData ? mat.clone() : mat);
    }

    default:
        qWarning() << "CVS::QImageToCvMat() - QImage format not handled in switch:" << inImage.format();
        break;
    }

    return cv::Mat();
}


MapEdit::MapEdit(QObject *parent)
    : QObject{parent}
{

}

void MapEdit::slot_newMapEdit(QString type,QStringList dataList)
{
    if(type == "startCreateMap" || type == "stopCreateMap")
    {
        if(type == "startCreateMap")
        {
            m_StartNewMap = true;
            qDebug()<<"startCreateMap="<<10/g_map_resolution;
            m_MapMat = cv::Mat::ones(10/g_map_resolution, 10/g_map_resolution, CV_8UC3) * 255;
            std::vector<cv::Mat> channels;
            cv::split(m_MapMat, channels);
            channels[1] = channels[0]; // 将蓝色通道的值复制到绿色通道上
            channels[2] = channels[0]; // 将蓝色通道的值复制到红色通道上
            cv::merge(channels, m_MapMat);

            QPixmap pixmap = cvMatToQPixmap(m_MapMat);
            emit sig_EndMapPixmap(pixmap);

        }

        else
            m_StartNewMap = false;
    }
    else if(type == g_RobotScan_multi && m_StartNewMap)
    {
        // // 设置位于第50行第10列的像素的第一个通道（蓝色通道）的值为255
        // image.at<cv::Vec3b>(50, 10)[0] = 255;
        // // 设置位于同一位置的绿色通道的值为128
        // image.at<cv::Vec3b>(50, 10)[1] = 128;
        // // 设置位于同一位置的红色通道的值为64
        // image.at<cv::Vec3b>(50, 10)[2] = 64;
        qreal max = 0;
        for(int i=0;i<dataList.length();i++)
        {
            if(QString(dataList[i]).toDouble() > max)
            {
                max = QString(dataList[i]).toDouble();
            }
        }
        qDebug()<<"max===="<<max<<max/g_map_resolution<<m_MapMat.cols<<m_MapMat.rows;
        cv::Mat FirstMapMat = cv::Mat::ones(max/g_map_resolution, max/g_map_resolution, CV_8UC3) * 255;
        std::vector<cv::Mat> channels;
        cv::split(FirstMapMat, channels);
        channels[1] = channels[0]; // 将蓝色通道的值复制到绿色通道上
        channels[2] = channels[0]; // 将蓝色通道的值复制到红色通道上
        cv::merge(channels, FirstMapMat);
        cv::Rect roi((FirstMapMat.cols - m_MapMat.cols)/2, (FirstMapMat.rows - m_MapMat.rows)/2, m_MapMat.cols, m_MapMat.rows); // 定义从(1,1)开始的区域
        qDebug()<<"--"<<(FirstMapMat.cols - m_MapMat.cols)/2<<(FirstMapMat.rows - m_MapMat.rows)/2<<m_MapMat.cols<<m_MapMat.rows;
        // 将replacement复制到src的roi区域
        m_MapMat.copyTo(FirstMapMat(roi));
        for(int i=0;i<dataList.length();i++)
        {
            qreal len = QString(dataList[i]).toDouble() / g_map_resolution;
            qreal jiaodu = 180-i;
            //x=r*cos角 y=r*sin角
            qreal hudu = jiaodu/180*3.1416;
            qreal X = len * cos(hudu) + (FirstMapMat.cols/2);
            qreal Y = len * sin(hudu) + (FirstMapMat.rows/2);
            cv::Point center(X, Y);
            cv::Scalar color = cv::Scalar(0, 0, 0);
            // 线条粗细，-1表示填充圆
            int thickness = -1;
            // 半径设置为1，表示画一个点
            int radius = 2;
            // 画圆
            cv::circle(FirstMapMat, center, radius, color, thickness);
        }
        FirstMapMat.copyTo(m_MapMat);
        QPixmap pixmap = cvMatToQPixmap(m_MapMat);
        emit sig_EndMapPixmap(pixmap);
    }

    else if(type == "Eraser")
    {
        qDebug()<<"dataList="<<dataList;
        int x_start = QString(dataList[0]).toDouble(); // 墙的厚度
        int x_end = x_start + QString(dataList[2]).toDouble(); // 墙的厚度
        int y_start = QString(dataList[1]).toDouble();
        int y_end = y_start+QString(dataList[3]).toDouble();

        if(x_start < 0)
            x_start = 0;
        if(y_start < 0)
            y_start = 0;
        if(x_end < 0)
            x_end = 0;
        if(y_end < 0)
            y_end = 0;
        if(x_start > m_MapMat.cols)
            x_start = m_MapMat.cols;
        if(y_start > m_MapMat.rows)
            y_start = m_MapMat.rows;
        if(x_end > m_MapMat.cols)
            x_end = m_MapMat.cols;
        if(y_end > m_MapMat.rows)
            y_end = m_MapMat.rows;

        // 定义矩形区域的位置和大小
        cv::Rect region(x_start, y_start, x_end-x_start, y_end-y_start);
        // 在图像中选定区域
        cv::Mat regionOfInterest = m_MapMat(region);
        // 将选定区域变成白色
        cv::Scalar redColor(255, 255, 255); // B, G, R
        if(m_Action_Data == "black")
            redColor = cv::Scalar(0,0,0);
        regionOfInterest.setTo(redColor);

        QPixmap pixmap = cvMatToQPixmap(m_MapMat);
        emit sig_EndMapPixmap(pixmap);

    }

    else if(type == "VirtualWallStart")
    {
        qDebug()<<"VirtualWallStart="<<dataList<<m_MapMat.cols<<m_MapMat.rows;
        VirtualWall_X = QString(dataList[0]).toDouble();
        VirtualWall_Y = QString(dataList[1]).toDouble();
        if(VirtualWall_X < 0)
            VirtualWall_X = 0;
        if(VirtualWall_Y < 0)
            VirtualWall_Y = 0;
        if(VirtualWall_X > m_MapMat.cols)
            VirtualWall_X = m_MapMat.cols;
        if(VirtualWall_Y > m_MapMat.rows)
            VirtualWall_Y = m_MapMat.rows;
        m_isVirtualWal = true;
        qDebug()<<"start------------------"<<VirtualWall_X<<VirtualWall_Y;
    }
    else if((type == "VirtualWallEnd" || type == "VirtualWallEnd_Release") && m_isVirtualWal)
    {
        qDebug()<<"VirtualWallEnd="<<dataList;

        int x_end = QString(dataList[0]).toDouble();
        int y_end = QString(dataList[1]).toDouble();
        if(x_end < 0)
            x_end = 0;
        if(y_end < 0)
            y_end = 0;
        if(x_end > m_MapMat.cols)
            x_end = m_MapMat.cols;
        if(y_end > m_MapMat.rows)
            y_end = m_MapMat.rows;


        cv::Mat VirtualWallMat;
        if(type == "VirtualWallEnd_Release")
        {
            VirtualWallMat = m_MapMat;
            m_isVirtualWal = false;
        }
        else
        {
            m_MapMat.copyTo(VirtualWallMat);
        }

        cv::line(VirtualWallMat, cv::Point(VirtualWall_X, VirtualWall_Y), cv::Point(x_end, y_end), cv::Scalar(0, 0, 0), 1);

        // double m_K = double(double(y_end-VirtualWall_Y)/double(x_end-VirtualWall_X));
        // double m_B = double(VirtualWall_Y-double(m_K*VirtualWall_X));
        // int x_min,x_max;
        // if(x_end > VirtualWall_X)
        // {
        //     x_min = VirtualWall_X;x_max = x_end;
        // }
        // else
        // {
        //     x_min = x_end; x_max = VirtualWall_X;
        // }
        // for(int i=x_min;i<x_max;i++)
        // {
        //     // 定义矩形区域的位置和大小
        //     cv::Rect region(i, i*m_K+m_B, 1, 1);
        //     // 在图像中选定区域
        //     cv::Mat regionOfInterest = VirtualWallMat(region);
        //     // 将选定区域变成白色
        //     cv::Scalar redColor(0, 0, 0); // B, G, R
        //     regionOfInterest.setTo(redColor);
        // }

        QPixmap pixmap = cvMatToQPixmap(VirtualWallMat);
        emit sig_EndMapPixmap(pixmap);
    }
}

void MapEdit::slot_MapPixmap(QPixmap pixmap,QString data)
{
    qDebug()<<" MapEdit::slot_MapPixmap"<<pixmap.width()<<pixmap.height()<<data;
    m_Action_Data = data;
    m_MapMat = QImageToCvMat(pixmap.toImage(),true);
}
